﻿/*
 * scadaloader.cpp
 *
 *  Created on: 2017年11月22日
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_SCADA DM_API_EXPORT

#include <dm/scada/scadaloader.hpp>
#include <dm/scada/scada.hpp>

#include <dm/os/log/logger.hpp>

#include <dm/env/cfg.hpp>

#include <dm/os/db/db.hpp>
#include <dm/os/db/resultset.hpp>
#include <dm/scoped_ptr.hpp>

#include <dm/scada/cfg.hpp>

#include <dm/scada/scadainfo.hpp>

#include <dm/scada/deviceinfo.hpp>
#include <dm/scada/statusinfo.hpp>
#include <dm/scada/statusdescinfo.hpp>
#include <dm/scada/discreteinfo.hpp>
#include <dm/scada/discretedescinfo.hpp>
#include <dm/scada/measureinfo.hpp>
#include <dm/scada/cumulantinfo.hpp>
#include <dm/scada/remotectlinfo.hpp>
#include <dm/scada/remotectldescinfo.hpp>
#include <dm/scada/parainfo.hpp>
#include <dm/scada/actioninfo.hpp>
#include <dm/scada/actiondescinfo.hpp>

#include <dm/scada/logicdeviceinfo.hpp>

namespace dm{
namespace scada{

static const char * logModule = "CScadaLoader.scada.dm";

CScadaLoader::CScadaLoader( CScada* scada ){
	dm::env::CCfg& cfg = dm::env::CCfg::ins();

	dm::TScopedPtr<dm::os::CDb> db(dm::os::createDb(cfg.scada_dbName().c_str(),cfg.scada_dbHost().c_str(),cfg.scada_dbEngine().c_str()));
	if( !db->connect(cfg.scada_dbUsr().c_str(),cfg.scada_dbPwd().c_str()) ){
		log().error( THISMODULE "连接数据库失败%s@%s.%s",cfg.scada_dbUsr().c_str(),cfg.scada_dbHost().c_str(),cfg.scada_dbName().c_str());
	}else{
		const CScadaInfo* info = scada->info();

		if( !load(*db,scada->m_deviceInfos,info->deviceCount()) ){
			log().error( THISMODULE "初始化设备信息失败");
			return;
		}

		if( !load(*db,scada->m_statusDescInfos,info->statusDescCount()) ){
			log().error( THISMODULE "初始化状态量描述信息失败");
			return;
		}

		if( !load(*db,scada->m_discreteDescInfos,info->discreteDescCount()) ){
			log().error( THISMODULE "初始化离散量描述信息失败");
			return;
		}

		if( !load(*db,scada->m_remoteCtlDescInfos,info->remoteCtlDescCount()) ){
			log().error( THISMODULE "初始化远控描述信息失败");
			return;
		}

		if( !load(*db,scada->m_actionDescInfos,info->actionDescCount()) ){
			log().error( THISMODULE "初始化动作描述信息失败");
			return;
		}

		TCfg<SStatusDescInfo> statusDescInfo(scada->statusDescInfos(),info->statusDescCount());
		if( !load(*db,scada->m_statusInfos,info->statusCount(),scada->m_deviceInfos,info->deviceCount(),statusDescInfo )){
			log().error( THISMODULE "初始化状态量信息失败");
			return;
		}

		TCfg<SDiscreteDescInfo> discreteDescInfo(scada->discreteDescInfos(),info->discreteDescCount());
		if( !load(*db,scada->m_discreteInfos,info->discreteCount(),scada->m_deviceInfos,info->deviceCount(),discreteDescInfo) ){
			log().error( THISMODULE "初始化离散量信息失败");
			return;
		}

		if( !load(*db,scada->m_measureInfos,info->measureCount(),scada->m_deviceInfos,info->deviceCount()) ){
			log().error( THISMODULE "初始化测量量信息失败");
			return;
		}

		if( !load(*db,scada->m_cumulantInfos,info->cumulantCount(),scada->m_deviceInfos,info->deviceCount()) ){
			log().error( THISMODULE "初始化累计量信息失败");
			return;
		}

		TCfg<SRemoteCtlDescInfo> remoteCtlDescInfo(scada->remoteCtlDescInfos(),info->remoteCtlDescCount());
		if( !load(*db,scada->m_remoteCtlInfos,info->remoteCtlCount(),scada->m_deviceInfos,info->deviceCount(),remoteCtlDescInfo) ){
			log().error( THISMODULE "初始化远控信息失败");
			return;
		}

		if( !load(*db,scada->m_parameterInfos,info->parameterCount(),scada->m_deviceInfos,info->deviceCount()) ){
			log().error( THISMODULE "初始化参数信息失败");
			return;
		}

		TCfg<SActionDescInfo> actionDescInfo(scada->actionDescInfos(),info->actionDescCount());
		if( !load(*db,scada->m_actionInfos,info->actionCount(),scada->m_deviceInfos,info->deviceCount(),actionDescInfo) ){
			log().error( THISMODULE "初始化动作信息失败");
			return;
		}

		if( !loadLogicDevice(*db,scada->m_logicDeviceInfos,info->logicDeviceCount()) ){
			log().error( THISMODULE "初始化逻辑设备信息失败");
			return;
		}

		TCfg<SStatusInfo> statusInfo(scada->statusInfos(),info->statusCount());
		if( !loadLogicStatus(*db,scada->m_map2Status,info->logicStatusCount(),scada->m_map2logicStatus,info->statusCount(),scada->m_logicDeviceInfos,info->logicDeviceCount(),statusInfo)){
			log().error( THISMODULE "初始化逻辑设备状态量映射失败");
			return;
		}

		TCfg<SDiscreteInfo> discreteInfo(scada->discreteInfos(),info->discreteCount());
		if( !loadLogicDiscrete(*db,scada->m_map2Discrete,info->logicDiscreteCount(),scada->m_map2logicDiscrete,info->discreteCount(),scada->m_logicDeviceInfos,info->logicDeviceCount(),discreteInfo)){
			log().error( THISMODULE "初始化逻辑设备离散量映射失败");
			return;
		}

		TCfg<SMeasureInfo> measureInfo(scada->measureInfos(),info->measureCount());
		if( !loadLogicMeasure(*db,scada->m_map2Measure,info->logicMeasureCount(),scada->m_map2logicMeasure,info->measureCount(),scada->m_logicDeviceInfos,info->logicDeviceCount(),measureInfo)){
			log().error( THISMODULE "初始化逻辑设备测量量映射失败");
			return;
		}

		TCfg<SCumulantInfo> cumulantInfo(scada->cumulantInfos(),info->cumulantCount());
		if( !loadLogicCumulant(*db,scada->m_map2Cumulant,info->logicCumulantCount(),scada->m_map2logicCumulant,info->cumulantCount(),scada->m_logicDeviceInfos,info->logicDeviceCount(),cumulantInfo)){
			log().error( THISMODULE "初始化逻辑设备累计量映射失败");
			return;
		}

		TCfg<SRemoteCtlInfo> remoteCtlInfo(scada->remoteCtlInfos(),info->remoteCtlCount());
		if( !loadLogicRemoteCtl(*db,scada->m_map2RemoteCtl,info->logicRemoteCtlCount(),scada->m_map2logicRemoteCtl,info->remoteCtlCount(),scada->m_logicDeviceInfos,info->logicDeviceCount(),remoteCtlInfo)){
			log().error( THISMODULE "初始化逻辑设备远控映射失败");
			return;
		}

		TCfg<SParaInfo> paraInfo(scada->parameterInfos(),info->parameterCount());
		if( !loadLogicParameter(*db,scada->m_map2Parameter,info->logicParameterCount(),scada->m_map2logicParameter,info->parameterCount(),scada->m_logicDeviceInfos,info->logicDeviceCount(),paraInfo)){
			log().error( THISMODULE "初始化逻辑设备参数映射失败");
			return;
		}

		TCfg<SActionInfo> actionInfo(scada->actionInfos(),info->actionCount());
		if( !loadLogicAction(*db,scada->m_map2Action,info->logicActionCount(),scada->m_map2logicAction,info->actionCount(),scada->m_logicDeviceInfos,info->logicDeviceCount(),actionInfo)){
			log().error( THISMODULE "初始化逻辑设备动作映射失败");
			return;
		}
	}
}

/**
 * @brief 加载设备信息
 * 
 * @param db 数据库连接
 * @param buf 设备信息缓冲区
 * @param size 设备数量
 * @return true 
 * @return false 
 */
bool CScadaLoader::load( os::CDb& db,SDeviceInfo* buf,const index_t& size ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置设备");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "设备缓冲区异常");
		return false;
	}

	dm::TScopedPtr<dm::os::CResultSet> rs(db.query("select id,name,descr from t_device order by no"));
	if( rs ){
		index_t i = 0;
		while( rs->next() ){
			if( i>=size ){
				log().warnning( THISMODULE "加载设备信息，系统缓冲区不够");
				return false;
			}

			buf[i].id = rs->asInt(0);
			buf[i].name = rs->asString(1);
			buf[i].desc = rs->asString(2);
			++i;
		}

		log().debug( THISMODULE "加载设备信息%d",i);

		return true;

	}else{
		log().error( THISMODULE "查询设备表失败");
		return false;
	}
}

/**
 * @brief 加载状态量描述信息
 * 
 * @param db 数据库连接
 * @param buf 状态量描述缓冲区
 * @param size 状态量描述数量
 * @return true 
 * @return false 
 */
bool CScadaLoader::load( os::CDb& db,SStatusDescInfo* buf,const index_t& size ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置状态量描述");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "状态量描述缓冲区异常");
		return false;
	}

	dm::TScopedPtr<dm::os::CResultSet> rs(db.query("select id,descr from t_status_desc order by no"));
	if( !rs ){
		log().error( THISMODULE "获取状态描述失败");
		return false;
	}

	index_t i = 0;
	while( rs->next() ){
		if( i>=size ){
			log().warnning( THISMODULE "加载状态描述信息，系统缓冲区不够");
			return false;
		}

		buf[i].id = rs->asInt(0);
		buf[i].desc = rs->asString(1);
		++i;
	}

	log().debug( THISMODULE "加载状态描述%d",i);
	return true;
}

bool CScadaLoader::load( os::CDb& db,SDiscreteDescInfo* buf,const index_t& size ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置离散量描述");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "离散量缓冲区异常");
		return false;
	}

	dm::TScopedPtr<dm::os::CResultSet> rs(db.query("select id,descr from t_discrete_desc order by no"));
	if( rs ){
		log().debug( THISMODULE "执行查询离散量描述成功");
	}

	index_t i = 0;
	while( rs->next() ){
		if( i>=size ){
			log().warnning( THISMODULE "加载离散量描述信息，系统缓冲区不够");
			return false;
		}

		buf[i].id = rs->asInt(0);
		buf[i].desc = rs->asString(1);
		++i;
	}

	log().debug( THISMODULE "加载离散量描述%d",i);

	return true;
}

bool CScadaLoader::load( os::CDb& db, SRemoteCtlDescInfo* buf,const index_t& size ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置远控描述");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "远控描述缓冲区异常");
		return false;
	}

	dm::TScopedPtr<dm::os::CResultSet> rs(db.query("select id,descr from t_remote_ctl_desc order by no"));
	if( !rs ){
		log().error( THISMODULE "执行查询远控描述成功");
		return false;
	}

	index_t i = 0;
	while( rs->next() ){
		if( i>=size ){
			log().warnning( THISMODULE "加载远动描述信息，系统缓冲区不够");
			return false;
		}

		buf[i].id = rs->asInt(0);
		buf[i].desc = rs->asString(1);
		++i;
	}

	log().debug( THISMODULE "加载远控描述%d",i);

	return true;
}

bool CScadaLoader::load( os::CDb& db,SActionDescInfo* buf,const index_t& size ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置动作描述");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "动作描述缓冲区异常");
		return false;
	}

	dm::TScopedPtr<dm::os::CResultSet> rs(db.query("select id,descr from t_action_desc order by no"));
	if( !rs ){
		log().error(THISMODULE "获取动作描述失败");
		return false;
	}

	index_t i = 0;
	while( rs->next() ){
		if( i>=size ){
			log().warnning( THISMODULE "加载动作描述信息，系统缓冲区不够");
			return false;
		}

		buf[i].id = rs->asInt(0);
		buf[i].desc = rs->asString(1);
		++i;
	}

	log().debug( THISMODULE "加载动作描述%d",i);
	return true;
}

bool CScadaLoader::load( os::CDb& db,SStatusInfo* buf,const index_t& size,SDeviceInfo* devices,const index_t& deviceSize,const TCfg<SStatusDescInfo>& desc ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置状态量");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "状态量缓冲区异常");
		return false;
	}

	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<deviceSize;++d ){
		devices[d].posOfStatus = rt;
		index_t num = 0;
		sprintf(sql,"select id,name,descr,level,desc_invoff,desc_off,desc_on,desc_invon,store_flag,gen_timed_flag,rpt_timed_flag from t_status where device=%d order by no",
				devices[d].id);

		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			log().debug( THISMODULE "执行查询设备%d状态信息成功",devices[d].id);
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载状态信息，系统缓冲区不够");
					return false;
				}

				buf[rt].id = rs->asInt(0);
				buf[rt].name = rs->asString(1);
				buf[rt].desc = rs->asString(2);
				buf[rt].level = SStatusInfo::ELevel(rs->asInt(3));

				if( rs->isNull(4) )
					buf[rt].desc_invOff = -1;
				else
					buf[rt].desc_invOff = desc.indexOf(rs->asInt(4));

				if( rs->isNull(5) )
					buf[rt].desc_off = -1;
				else
					buf[rt].desc_off = desc.indexOf( rs->asInt(5));

				if( rs->isNull(6) )
					buf[rt].desc_on = -1;
				else
					buf[rt].desc_on = desc.indexOf( rs->asInt(6));

				if( rs->isNull(7) )
					buf[rt].desc_invOn = -1;
				else
					buf[rt].desc_invOn = desc.indexOf( rs->asInt(7));

				buf[rt].setFlagSave( !rs->isNull(8) && rs->asInt(8)==1 );
				buf[rt].setFlagGenTimed( !rs->isNull(9) && rs->asInt(9)==1 );
				buf[rt].setFlagReportTimed( !rs->isNull(10) && rs->asInt(10)==1 );

				++rt;
				++num;
			}

			devices[d].sizeOfStatus = num;
			log().debug( THISMODULE "加载设备%d状态%d",devices[d].id,num);
		}
	}
	log().debug( THISMODULE "加载状态%d",rt);

	return true;
}


bool CScadaLoader::load( os::CDb& db,SDiscreteInfo* buf,const index_t& size,SDeviceInfo* devices,const index_t& deviceSize,const TCfg<SDiscreteDescInfo>& desc ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置离散量");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "离散量缓冲区异常");
		return false;
	}

	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<deviceSize;++d ){
		devices[d].posOfDiscrete = rt;
		index_t num = 0;
		sprintf(sql,"select id,name,descr,desc_start,desc_num,store_flag,gen_timed_flag,rpt_timed_flag from t_discrete where device=%d order by no",
				devices[d].id);

		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			log().debug( THISMODULE "执行查询设备%d离散量信息成功",devices[d].id);
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载离散量信息，系统缓冲区不够");
					return false;
				}

				buf[rt].id = rs->asInt(0);
				buf[rt].name = rs->asString(1);
				buf[rt].desc = rs->asString(2);
				buf[rt].desc_pos = desc.indexOf( rs->asInt(3));
				buf[rt].desc_num = rs->asInt(4);

				buf[rt].setFlagSave( !rs->isNull(5) && rs->asInt(5)==1 );
				buf[rt].setFlagGenTimed( !rs->isNull(6) && rs->asInt(6)==1 );
				buf[rt].setFlagReportTimed( !rs->isNull(7) && rs->asInt(7)==1 );

				++rt;
				++num;
			}

			devices[d].sizeOfDiscrete = num;
			log().debug( THISMODULE "加载设备%d离散量%d",devices[d].id,num);
		}
	}
	log().debug( THISMODULE "加载离散量信息%d",rt);

	return true;
}

bool CScadaLoader::load( os::CDb& db,SMeasureInfo* buf,const index_t& size,SDeviceInfo* devices,const index_t& deviceSize ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置测量量");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "测量量缓冲区异常");
		return false;
	}
	
	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<deviceSize;++d ){
		devices[d].posOfMeasure = rt;
		index_t num = 0;
		sprintf(sql,"select id,name,descr,unit,delta,value_base,value_coef,store_flag,gen_timed_flag,rpt_timed_flag from t_measure where device=%d order by no",
				devices[d].id);

		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			log().debug( THISMODULE "执行查询设备%d测量量信息成功",devices[d].id);
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载测量量信息，系统缓冲区不够");
					return false;
				}

				buf[rt].id = rs->asInt(0);
				buf[rt].name = rs->asString(1);
				buf[rt].desc = rs->asString(2);
				buf[rt].unit = rs->asString(3);
				buf[rt].delta = rs->asDouble(4);
				buf[rt].base = rs->asDouble(5);
				buf[rt].coef = rs->asDouble(6);

				buf[rt].setFlagSave( !rs->isNull(7) && rs->asInt(7)==1 );
				buf[rt].setFlagGenTimed( !rs->isNull(8) && rs->asInt(8)==1 );
				buf[rt].setFlagReportTimed( !rs->isNull(9) && rs->asInt(9)==1 );

				++rt;
				++num;
			}

			devices[d].sizeOfMeasure = num;
			log().debug( THISMODULE "加载设备%d测量量%d",devices[d].id,num);
		}
	}
	log().debug( THISMODULE "加载测量量信息%d",rt);

	return true;
}

bool CScadaLoader::load( os::CDb& db,SCumulantInfo* buf,const index_t& size,SDeviceInfo* devices,const index_t& deviceSize ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置累计量");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "累计量缓冲区异常");
		return false;
	}

	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<deviceSize;++d ){
		devices[d].posOfCumulant = rt;
		index_t num = 0;
		sprintf(sql,"select id,name,descr,max,delta,coef,store_flag,gen_timed_flag,rpt_timed_flag from t_cumulant where device=%d order by no",
				devices[d].id);

		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			log().debug( THISMODULE "执行查询设备%d累计量信息成功",devices[d].id);
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载累计量信息，系统缓冲区不够");
					return false;
				}

				buf[rt].id = rs->asInt(0);
				buf[rt].name = rs->asString(1);
				buf[rt].desc = rs->asString(2);
				buf[rt].maxCode = rs->asInt(3);
				buf[rt].delta = rs->asInt(4);
				buf[rt].coef = rs->asDouble(5);

				buf[rt].setFlagSave( !rs->isNull(6) && rs->asInt(6)==1 );
				buf[rt].setFlagGenTimed( !rs->isNull(7) && rs->asInt(7)==1 );
				buf[rt].setFlagReportTimed( !rs->isNull(8) && rs->asInt(8)==1 );

				++rt;
				++num;
			}

			devices[d].sizeOfCumulant = num;
			log().debug( THISMODULE "加载设备%d累计量%d",devices[d].id,num);
		}
	}
	log().debug( THISMODULE "加载累计量信息%d",rt);

	return true;
}

bool CScadaLoader::load( os::CDb& db,SRemoteCtlInfo* buf,const index_t& size,SDeviceInfo* devices,const index_t& deviceSize,const TCfg<SRemoteCtlDescInfo>& desc ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置远控");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "远控缓冲区异常");
		return false;
	}

	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<deviceSize;++d ){
		devices[d].posOfTeleCtl = rt;
		index_t num = 0;
		sprintf(sql,"select id,name,descr,desc_preopen,desc_preclose,desc_close,desc_open from t_remote_ctl where device=%d order by no",
				devices[d].id);
		
		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			log().debug( THISMODULE "执行查询设备%d远动信息成功",devices[d].id);
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载远动信息，系统缓冲区不够");
					return false;
				}

				buf[rt].id = rs->asInt(0);
				buf[rt].name = rs->asString(1);
				buf[rt].desc = rs->asString(2);

				if( rs->isNull(3) )
					buf[rt].descPreOpen = -1;
				else
					buf[rt].descPreOpen = desc.indexOf( rs->asInt(3));

				if( rs->isNull(4) )
					buf[rt].descPreClose = -1;
				else
					buf[rt].descPreClose = desc.indexOf( rs->asInt(4));

				if( rs->isNull(5) )
					buf[rt].descClose = -1;
				else
					buf[rt].descClose = desc.indexOf( rs->asInt(5));

				if( rs->isNull(6) )
					buf[rt].descOpen = -1;
				else
					buf[rt].descOpen = desc.indexOf( rs->asInt(6));

				++rt;
				++num;
			}

			devices[d].sizeOfTeleCtl = num;
			log().debug( THISMODULE "加载设备%d远控%d",devices[d].id,num);
		}
	}
	log().debug( THISMODULE "加载远控信息%d",rt);

	return true;
}

bool CScadaLoader::load( os::CDb& db,SParaInfo* buf,const index_t& size,SDeviceInfo* devices,const index_t& deviceSize ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置参数");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "参数缓冲区异常");
		return false;
	}

	index_t rt = 0;
	char sql[256];
	for( int d=0;d<deviceSize;++d ){
		devices[d].posOfPara = rt;
		index_t num = 0;
		sprintf(sql,"select id,name,descr from t_parameter where device=%d order by no",
				devices[d].id);

		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			log().debug( THISMODULE "执行查询设备%d参数信息成功",devices[d].id);
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载参数信息，系统缓冲区不够");
					return false;
				}

				buf[rt].id = rs->asInt(0);
				buf[rt].name = rs->asString(1);
				buf[rt].desc = rs->asString(2);

				++rt;
				++num;
			}

			devices[d].sizeOfPara = num;
			log().debug( THISMODULE "加载设备%d参数%d",devices[d].id,num);
		}
	}
	log().debug( THISMODULE "加载参数信息%d",rt);

	return true;
}


bool CScadaLoader::load( os::CDb& db,SActionInfo* buf,const index_t& size,SDeviceInfo* devices,const index_t& deviceSize,const TCfg<SActionDescInfo>& desc ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置动作");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "动作缓冲区异常");
		return false;
	}
	
	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<deviceSize;++d ){
		devices[d].posOfAction = rt;
		index_t num = 0;
		sprintf(sql,"select id,name,descr,level,desc_invoff,desc_off,desc_on,desc_invon,store_flag,rpt_timed_flag from t_action where device=%d order by no",
				devices[d].id);

		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			log().debug( THISMODULE "执行查询设备%d状态信息成功",devices[d].id);
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载状态信息，系统缓冲区不够");
					return false;
				}

				buf[rt].id = rs->asInt(0);
				buf[rt].name = rs->asString(1);
				buf[rt].desc = rs->asString(2);
				buf[rt].level = SActionInfo::ELevel(rs->asInt(3));

				if( rs->isNull(4) )
					buf[rt].desc_invOff = -1;
				else
					buf[rt].desc_invOff = desc.indexOf( rs->asInt(4));

				if( rs->isNull(5) )
					buf[rt].desc_off = -1;
				else
					buf[rt].desc_off = desc.indexOf( rs->asInt(5));

				if( rs->isNull(6) )
					buf[rt].desc_on = -1;
				else
					buf[rt].desc_on = desc.indexOf( rs->asInt(6));

				if( rs->isNull(7) )
					buf[rt].desc_invOn = -1;
				else
					buf[rt].desc_invOn = desc.indexOf( rs->asInt(7));

				buf[rt].setFlagSave( !rs->isNull(8) && rs->asInt(8)==1 );
				buf[rt].setFlagReportTimed( !rs->isNull(9) && rs->asInt(9)==1 );

				++rt;
				++num;
			}

			devices[d].sizeOfAction = num;
			log().debug( THISMODULE "加载设备%d动作d",devices[d].id,num);
		}
	}
	log().debug( THISMODULE "加载状态%d",rt);

	return true;
}

bool CScadaLoader::loadLogicDevice( os::CDb& db,SLogicDeviceInfo* buf,const index_t& size ){
	if( size==0 ){
		log().debug(THISMODULE "系统未配置逻辑设备");
		return true;
	}

	if( buf==NULL ){
		log().error(THISMODULE "逻辑设备缓冲区异常");
		return false;
	}
	
	dm::TScopedPtr<dm::os::CResultSet> rs(db.query("select id,name,descr from t_logic_device order by no"));
	if( rs ){
		index_t rt = 0;
		while( rs->next() ){
			if( rt>=size ){
				log().warnning( THISMODULE "加载逻辑设备信息，系统缓冲区不够");
				return false;
			}

			buf[rt].id = rs->asInt(0);
			buf[rt].name = rs->asString(1);
			buf[rt].desc = rs->asString(2);

			++rt;
		}

		log().debug( THISMODULE "加载逻辑设备%d ",rt);

		return true;
	}else{
		log().error(THISMODULE "查询逻辑设备失败");
		return false;
	}
}

/**
 * @brief 加载逻辑状态量
 * 
 * @param db 数据库连接
 * @param map2devie 逻辑点映射到设备
 * @param size 逻辑映射到设备缓冲区大小
 * @param map2logic 映射到逻辑点
 * @param statussSize 状态量数量
 * @param logicDevices 逻辑设备信息
 * @param logicDeviceSize 逻辑设备数据
 * @param cfg 状态量信息
 * @return true 
 * @return false 
 */
bool CScadaLoader::loadLogicStatus( os::CDb& db,index_t* map2devie,const index_t& size,index_t* map2logic,const index_t& statussSize,SLogicDeviceInfo* logicDevices,const index_t& logicDeviceSize,const TCfg<SStatusInfo>& cfg ){
	index_t rt = 0;	// 逻辑点计数
	char sql[256];

	for( index_t d=0;d<logicDeviceSize;++d ){	// 每个逻辑设备执行
		logicDevices[d].posOfStatus = rt;	// 逻辑设备状态量起始偏移
		index_t num = 0;	// 本逻辑设备信号个数
		sprintf(sql,"select status from t_logic_status where logic_device=%d order by no",logicDevices[d].id);
		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载状态量映射信息，系统缓冲区不够");
					return false;
				}

				if( map2devie[rt]!=-1 ){
					log().warnning( THISMODULE "加载逻辑设备%d状态量%d索引被覆盖",logicDevices[d].id,rt);
				}
				map2devie[rt] = cfg.indexOf(rs->asInt(0));
				if( map2devie[rt]!=-1 )
					map2logic[ d*statussSize + map2devie[rt] ] = num;	// map2logic映射到索引号
				else{
					log().warnning( THISMODULE "加载逻辑设备%d状态量%d失败",logicDevices[d].id,rt);
				}

				++rt;
				++num;
			}

			logicDevices[d].sizeOfStatus = num;
			log().debug( THISMODULE "加载逻辑设备%d状态量%d",logicDevices[d].id,num);
		}else{
			log().error(THISMODULE "查询逻辑设备状态量映射失败");
			return false;
		}
	}

	return true;
}

bool CScadaLoader::loadLogicDiscrete( os::CDb& db,index_t* map2devie,const index_t& size,index_t* map2logic,const index_t& discreteSize,SLogicDeviceInfo* logicDevices,const index_t& logicDeviceSize,const TCfg<SDiscreteInfo>& cfg ){
	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<logicDeviceSize;++d ){
		logicDevices[d].posOfDiscrete = rt;
		index_t num = 0;
		sprintf(sql,"select discrete from t_logic_discrete where logic_device=%d order by no",logicDevices[d].id);
		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载离散量映射信息，系统缓冲区不够");
					return false;
				}

				if( map2devie[rt]!=-1 ){
					log().warnning( THISMODULE "加载逻辑设备%d离散量%d索引被覆盖",logicDevices[d].id,rt);
				}
				map2devie[rt] = cfg.indexOf(rs->asInt(0));
				if( map2devie[rt]!=-1 )
					map2logic[ d*discreteSize + map2devie[rt] ] = num;	// map2logic映射到索引号
				else{
					log().warnning( THISMODULE "加载逻辑设备%d离散量%d失败",logicDevices[d].id,rt);
				}

				++rt;
				++num;
			}

			logicDevices[d].sizeOfDiscrete = num;
			log().debug( THISMODULE "加载逻辑设备%d离散量%d",logicDevices[d].id,num);
		}else{
			log().error(THISMODULE "查询逻辑设备离散量映射失败");
			return false;
		}
	}

	return true;
}

bool CScadaLoader::loadLogicMeasure( os::CDb& db,index_t* map2devie,const index_t& size,index_t* map2logic,const index_t& measureSize,SLogicDeviceInfo* logicDevices,const index_t& logicDeviceSize,const TCfg<SMeasureInfo>& cfg ){
	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<logicDeviceSize;++d ){
		logicDevices[d].posOfMeasure = rt;
		index_t num = 0;
		sprintf(sql,"select measure from t_logic_measure where logic_device=%d order by no",logicDevices[d].id);
		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载测量量映射信息，系统缓冲区不够");
					return false;
				}

				if( map2devie[rt]!=-1 ){
					log().warnning( THISMODULE "加载逻辑设备%d测量量%d索引被覆盖",logicDevices[d].id,rt);
				}
				map2devie[rt] = cfg.indexOf(rs->asInt(0));
				if( map2devie[rt]!=-1 )
					map2logic[ d*measureSize + map2devie[rt] ] = num;	// map2logic映射到索引号
				else{
					log().warnning( THISMODULE "加载逻辑设备%d测量量%d失败",logicDevices[d].id,rt);
				}

				++rt;
				++num;
			}

			logicDevices[d].sizeOfMeasure = num;
			log().debug( THISMODULE "加载逻辑设备%d测量量%d",logicDevices[d].id,num);
		}else{
			log().error(THISMODULE "查询逻辑设备测量量映射失败");
			return false;
		}
	}

	return true;
}

bool CScadaLoader::loadLogicCumulant( os::CDb& db,index_t* map2devie,const index_t& size,index_t* map2logic,const index_t& cumulantSize,SLogicDeviceInfo* logicDevices,const index_t& logicDeviceSize,const TCfg<SCumulantInfo>& cfg ){
	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<logicDeviceSize;++d ){
		logicDevices[d].posOfCumulant = rt;
		index_t num = 0;
		sprintf(sql,"select cumulant from t_logic_cumulant where logic_device=%d order by no",logicDevices[d].id);
		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载累计量映射信息，系统缓冲区不够");
					return false;
				}

				if( map2devie[rt]!=-1 ){
					log().warnning( THISMODULE "加载逻辑设备%d累积量%d索引被覆盖",logicDevices[d].id,rt);
				}
				map2devie[rt] = cfg.indexOf(rs->asInt(0));
				if( map2devie[rt]!=-1 )
					map2logic[ d*cumulantSize + map2devie[rt] ] = num;	// map2logic映射到索引号
				else{
					log().warnning( THISMODULE "加载逻辑设备%d累计量%d失败",logicDevices[d].id,rt);
				}

				++rt;
				++num;
			}

			logicDevices[d].sizeOfCumulant = num;
			log().debug( THISMODULE "加载逻辑设备%d累计量%d",logicDevices[d].id,num);
		}else{
			log().error(THISMODULE "查询逻辑设备累计量映射失败");
			return false;
		}
	}

	return true;
}

bool CScadaLoader::loadLogicRemoteCtl( os::CDb& db,index_t* map2devie,const index_t& size,index_t* map2logic,const index_t& remoteCtlSize,SLogicDeviceInfo* logicDevices,const index_t& logicDeviceSize,const TCfg<SRemoteCtlInfo>& cfg ){
	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<logicDeviceSize;++d ){
		logicDevices[d].posOfRemoteCtl = rt;
		index_t num = 0;
		sprintf(sql,"select remote_ctl from t_logic_remotectl where logic_device=%d order by no",logicDevices[d].id);
		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载远控映射信息，系统缓冲区不够");
					return false;
				}

				if( map2devie[rt]!=-1 ){
					log().warnning( THISMODULE "加载逻辑设备%d远控%d索引被覆盖",logicDevices[d].id,rt);
				}
				map2devie[rt] = cfg.indexOf(rs->asInt(0));
				if( map2devie[rt]!=-1 )
					map2logic[ d*remoteCtlSize + map2devie[rt] ] = num;	// map2logic映射到索引号
				else{
					log().warnning( THISMODULE "加载逻辑设备%d远控%d失败",logicDevices[d].id,rt);
				}

				++rt;
				++num;
			}

			logicDevices[d].sizeOfRemoteCtl = num;
			log().debug( THISMODULE "加载逻辑设备%d远控%d",logicDevices[d].id,num);
		}else{
			log().error(THISMODULE "查询逻辑设备远控映射失败");
			return false;
		}
	}

	return true;
}

bool CScadaLoader::loadLogicParameter( os::CDb& db,index_t* map2devie,const index_t& size,index_t* map2logic,const index_t& parameterSize,SLogicDeviceInfo* logicDevices,const index_t& logicDeviceSize,const TCfg<SParaInfo>& cfg ){
	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<logicDeviceSize;++d ){
		logicDevices[d].posOfParameter = rt;
		index_t num = 0;
		sprintf(sql,"select parameter from t_logic_parameter where logic_device=%d order by no",logicDevices[d].id);
		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载参数信息，系统缓冲区不够");
					return false;
				}

				if( map2devie[rt]!=-1 ){
					log().warnning( THISMODULE "加载逻辑设备%d参数%d索引被覆盖",logicDevices[d].id,rt);
				}

				map2devie[rt] = cfg.indexOf(rs->asInt(0));
				if( map2devie[rt]!=-1 )
					map2logic[ d*parameterSize + map2devie[rt] ] = num;	// map2logic映射到索引号
				else{
					log().warnning( THISMODULE "加载逻辑设备%d参数%d失败",logicDevices[d].id,rt);
				}

				++rt;
				++num;
			}

			logicDevices[d].sizeOfParameter = num;
			log().debug( THISMODULE "加载逻辑设备%d参数%d",logicDevices[d].id,num);
		}else{
			log().error(THISMODULE "查询逻辑设备参数映射失败");
			return false;
		}
	}

	return true;
}

bool CScadaLoader::loadLogicAction( os::CDb& db,index_t* map2devie,const index_t& size,index_t* map2logic,const index_t& actionSize,SLogicDeviceInfo* logicDevices,const index_t& logicDeviceSize,const TCfg<SActionInfo>& cfg ){
	index_t rt = 0;
	char sql[256];
	for( index_t d=0;d<logicDeviceSize;++d ){
		logicDevices[d].posOfAction = rt;
		int num = 0;
		sprintf(sql,"select action from t_logic_action where logic_device=%d order by no",logicDevices[d].id);
		dm::TScopedPtr<dm::os::CResultSet> rs(db.query(sql));
		if( rs ){
			while( rs->next() ){
				if( rt>=size ){
					log().warnning( THISMODULE "加载动作信息，系统缓冲区不够");
					return false;
				}

				if( map2devie[rt]!=-1 ){
					log().warnning( THISMODULE "加载逻辑设备%d动作%d索引被覆盖",logicDevices[d].id,rt);
				}
				map2devie[rt] = cfg.indexOf(rs->asInt(0));
				if( map2devie[rt]!=-1 )
					map2logic[ d*actionSize + map2devie[rt] ] = num;	// map2logic映射到索引号
				else{
					log().warnning( THISMODULE "加载逻辑设备%d动作%d失败",logicDevices[d].id,rt);
				}

				++rt;
				++num;
			}

			logicDevices[d].sizeOfAction = num;
			log().debug( THISMODULE "加载逻辑设备%d动作%d",logicDevices[d].id,num);
		}else{
			log().error(THISMODULE "查询逻辑设备动作映射失败");
			return false;
		}
	}

	return true;
}

}
}
